#include "FontParser.h"
#include "..\utils\Log.h"
#include "..\utils\PlainTextReader.h"
#include "..\base\Engine.h"
#include "..\game\World.h"
#include "..\content\Texture.h"
#include "..\content\BitmapFont.h"

namespace ds {

bool FontParser::isSupported(const std::string& fileEnding) const {
	bool ret = false;
	if ( fileEnding == ".fnt" ) {
		ret = true;
	}
	return ret;
}

void FontParser::loadTextFile(const ResourceFile& resourceFile,DeclarationManager* declarationManager) {
	JSONReader reader;
	if ( reader.parse(resourceFile.fqName.c_str()) ) {
		std::vector<Category*> categories = reader.getCategories();
		for ( size_t i = 0; i < categories.size(); ++i ) {
			Category* c = categories[i];
			if ( c->getName() == "font") {
				ResourceDeclaration* decl = parseCategory(c);
				if ( decl != 0 ) {
					declarationManager->addDeclaration(decl);
				}
			}
		}
	}
}

ResourceDeclaration* FontParser::parseCategory(Category* category) {
	if ( category->hasProperty("name") ) {					
		std::string name = category->getProperty("name");
		LOGC(logINFO,"FontParser") << "Parsing font definition " << name;
		FontDecl* decl = new FontDecl(name);		
		decl->setTexture(category->getProperty("texture"));
		decl->setStartChar(category->read<int>("start_char",32));
		decl->setEndChar(category->read<int>("end_char",127));
		decl->setHeight(category->read<int>("char_height",0));
		decl->setTexWidth(category->read<int>("width",0));
		decl->setTexHeight(category->read<int>("height",0));
		decl->setStartX(category->read<int>("start_x",0));
		decl->setStartY(category->read<int>("start_y",0));
		decl->setPadding(category->read<int>("padding",0));		
		return decl;
	}
	else {
		LOG(logERROR) << "missing name property detected";
		return 0;
	}
}

void FontParser::createResource(ResourceDeclaration* declaration) {
	FontDecl* td = static_cast<FontDecl*>(declaration);
	std::string name(td->getName());
	LOGC(logINFO,"FontParser") << "--------------------------------------------";
	LOGC(logINFO,"FontParser") << "Creating font resource: " << name;
	BMFontDefinition definition = td->getFontDefinition();
	LOGC(logINFO,"FontParser") << "-- Texture: " << definition.texture;
	Texture* tex = gEngine->getResourceManager().getTextureByName(definition.texture.c_str());
	if ( tex != 0 ) {
		ResourceHandle rh = gEngine->getResourceManager().createBitmapFont(name.c_str(),definition.startChar,definition.charHeight,definition.startX,definition.startY,tex->getWidth());
		BitmapFont* bf = gEngine->getResourceManager().getBitmapFont(rh);
		tex->lock();
		int x = definition.startX+definition.padding-1;
		int y = definition.startY+definition.padding;
		uint32 ascii = definition.startChar;
		Color c = tex->getColor(x,y);
		bool running = true;
		bool isChar = false;
		int charStartedX = 0;
		int charStartedY = 0;
		while ( running ) {
			++x;
			if ( x > (definition.startX+definition.texWidth) ) {
				x = definition.startX+definition.padding-1;
				y += definition.padding + definition.charHeight+1;
				isChar = false;
			}
			if ( y > (definition.startY+definition.texHeight) ) {
				running = false;
			}
			c = tex->getColor(x,y);
			if ( !isFillColor(c) && !isChar ) {
				isChar = true;
				charStartedX = x;
				charStartedY = y;				
			}
			else if ( isFillColor(c) && isChar ) {
				isChar = false;
				int width = x - charStartedX - 1;
				LOGC(logINFO,"FontParser") << "char " << ascii << " found at " << charStartedX << " " << charStartedY << " width " << width;
				bf->addChar(ascii,charStartedX+1,charStartedY+1,width);
				++ascii;
			}
		}
		tex->unlock();
	}
	else {
		LOGC(logERROR,"FontParser") << "No matching texture found in ResouceManager";
	}
	LOGC(logINFO,"FontParser") << "--------------------------------------------";
}

bool FontParser::isFillColor(const Color& col) {
	return col.r == 1.0f && col.g == 0.0f && col.b == 1.0f;
}

}
